/*
  Copyright 2011 Frogtek BOP LLC

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */
package org.frogtek.database;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import org.frogtek.database.interfaces.Database;

/**
 * This class manages all the connections between the bl and the database
 * 
 * @author Pablo Abad <pablo@frogtek.org> & Pedro Fraca <pedro@frogtek.org>
 *
 */
public class DatabaseBackupUtils {
	
	private String EXTERNAL_BD_PATH = "";
	
	public DatabaseBackupUtils(String externalDbPath) {
		EXTERNAL_BD_PATH = externalDbPath;
	}
	
	public int copyDataBaseAndReturn(String posName, String date, Database myDatabase) {
		try {
			copyDataBase(posName,date, myDatabase);
			return 0;
		} catch (IOException e) {
			e.printStackTrace();
			return -1;
		}
	}

      /**
     * Copies your database from your local assets-folder to the just created empty database in the
     * system folder, from where it can be accessed and handled.
     * This is done by transfering bytestream.
     * */
    private void copyDataBase(String nameDatabaseDestination, Database myDatabase) throws IOException {

        //Open your local db as the input stream
        File file = new File(myDatabase.getLocalPath() + myDatabase.getDatabaseName());
        if (file.exists()) {
            // Path to the just created empty db

            checkExternalfolder();
            
            //Now check if the file exists
            File dbFile = new File(nameDatabaseDestination);

            if (dbFile.exists() == false) {
                //If not create it
                dbFile.createNewFile();
            }

            copyFile(nameDatabaseDestination, file);
        }
    }

	private File checkExternalfolder() {
		//First check if the folder is yet in the file system
		File fileOut = new File(EXTERNAL_BD_PATH);
		if (fileOut.exists() == false) {
		    //if not exists creates all the tree
		    fileOut.mkdirs();
		}
		return fileOut;
	}
    
    public void copyDataBase(Database myDatabase) throws IOException {
    	String initialName = EXTERNAL_BD_PATH + myDatabase.getDatabaseName() + ".fgk";
    	copyDataBase(initialName,myDatabase);
    }
    
    public void copyDataBase(String posName, String date, Database myDatabase) throws IOException {
    	String initialName = EXTERNAL_BD_PATH + myDatabase.getDatabaseName() + "_" + posName + "_" + date + ".fgk";
    	copyDataBase(initialName,myDatabase);
    }

	/**
     * Copies your database from your application sd-card folder to the just created empty database in the
     * system folder, from where it can be accessed and handled. A restoration of the Database
     * This is done by transfering bytestream.
     * 
     * I uses the most new database it finds in the folder of Databases
     * */
	public String restoreDataBase(Database myDatabase) {

        String output = "";

        File fileOut = checkExternalfolder();
        
        File file = new File(EXTERNAL_BD_PATH + myDatabase.getDatabaseName() + ".fgk");
        if(fileOut.isDirectory()){
        	File[] possibleDatabasesToRecover = fileOut.listFiles();
        	if(possibleDatabasesToRecover!=null){
        		long dateFileWasLastModified= 0;
        		for (int i = 0; i < possibleDatabasesToRecover.length; i++) {
        			if(possibleDatabasesToRecover[i].lastModified() > dateFileWasLastModified){
        				file = possibleDatabasesToRecover[i];
        				dateFileWasLastModified = possibleDatabasesToRecover[i].lastModified();
        			}
				}
        	}
        }

        try {
           if (file.exists()) {
              output = createDatabaseFromSDFile(file,myDatabase);
           }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return output;
    }

    /**
     * Creates a new SD file with the name passed as parameter.
     *
     * @return String containing the name of the file to be created.
     */
    private String createDatabaseFromSDFile(File fileName,Database myDatabase) throws IOException {

        // Path to the just created empty db
    	String databaseNameDestination = myDatabase.getLocalPath() + myDatabase.getDatabaseName();

        //Now check if the file exists
        File dbFile = new File(databaseNameDestination);

        if (dbFile.exists() == false) {
            //If not create it
            dbFile.createNewFile();
        }
        
        copyFile(databaseNameDestination,fileName);

        return fileName.getName();
    }

    private void copyFile(String nameDatabaseDestination, File databaseFileOrigin) throws FileNotFoundException, IOException {
		FileInputStream myInput = new FileInputStream(databaseFileOrigin);
		OutputStream myOutput = new FileOutputStream(nameDatabaseDestination);

		byte[] buffer = new byte[1024];
		int length;
		while ((length = myInput.read(buffer)) > 0) {
		    myOutput.write(buffer, 0, length);
		}
		//transfer bytes from the inputfile to the outputfile
		//Close the streams
		myOutput.flush();
		myOutput.close();
		myInput.close();
	}
}

